<?php
namespace RestClient;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use Firebase\JWT\JWT;
use Firebase\JWT\SignatureInvalidException;
use Firebase\JWT\BeforeValidException;

class RestClient
{
    private static $url;
    private $accessToken;
    private $jwtKey;

    public function __construct($url = null, $jwtKey = null)
    {
        $this->url = $url ?: C('API_HOST');
        $this->jwtKey = $jwtKey ?: C('JWT_KEY');
    }

    public function setAccessToken($accessToken)
    {
        $this->accessToken = $accessToken;
    }

    public function get($resource, $queryParams = [], $headers)
    {
        $queryParams['iat'] = time();
        $queryParams['exp'] = $queryParams['iat'] + 60;
        $params = [];
        $parmas['jwt'] = JWT::encode($queryParams, $this->jwtKey);
        $options = [
            'query' => $params,
            'headers' => $headers,
        ];
        return $this->request('GET', $resource, $options);
    }

    public function request($method, $resource, $options)
    {
        $client = new Client([
            'base_uri' => $this->url,
        ]);
        if ($this->accessToken) $options['headers']['Authorization'] = $this->accessToken;
        try {
            $response = $client->request($method, $resource, $options);
            // return new RestResponse($response);
            $contents = $response->getBody()->getContents();
            $token = json_decode($contents, true);
            try {
                $data = JWT::decode($token['token'], $this->jwtKey, ['HS256']);
                $ret = [];
                if (isset($data->data)) $ret['data'] = $data->data;
                if (isset($data->pagination)) $ret['pagination'] = $data->pagination;
                return $ret;
            } catch (SignatureInvalidException $e) {
                throw $e;
            } catch (BeforeValidException $e) {
                throw $e;
            } catch (\Exception $e) {
                throw $e;
            }
        } catch (ClientException $e) {
            $response = $e->getResponse();
            $statusCode = $response->getStatusCode();
            $errors = json_decode($response->getBody()->getContents(), true);
            throw new RestException($statusCode, $errors['message'], $errors['error_code']);
        }
    }
}